package com.vipsoft.base.core;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vipsoft.base.util.ConvertUtil;
import org.apache.catalina.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class BaseController {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    protected <T> Page buildPage(PageParam param) {
        List<OrderItem> orderItems = new ArrayList<>();

        if (orderItems.size() == 0) {
            //默认按创建时间排序
            orderItems.add(OrderItem.desc("create_time"));
        }
        Page page = new Page(param.getPageCount(), param.getPageSize());
        page.setOrders(orderItems);
        return page;
    }

    /**
     * 根据 URL 参考，构建 分面排序
     *
     * @param pageParam
     * @Deprecated 参数放Body中
     */
    @Deprecated
    protected Page buildPage2(PageParam pageParam) {
        ServletRequestAttributes servletRequest = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String ascs = servletRequest.getRequest().getParameter("ascs");  //格式是 "field1,field2,..."
        String descs = servletRequest.getRequest().getParameter("descs"); //格式是 "field1,field2,..."
        List<OrderItem> orderItems = Stream.of(descs, ascs)
                .filter(StrUtil::isNotEmpty) //如果 URL 中没有 descs，ascs，则排除
                .flatMap(str -> Arrays.stream(str.split(","))) //扁平化
                .filter(StrUtil::isNotEmpty) // Split 后会产生一个空数组，等同于 .filter(field -> StrUtil.isNotEmpty(field))  //过滤掉""字符
                //.map(field -> ConvertUtil.getAnnotationValue(SysRole.class, field, TableField.class)) // 获取列名（这里假设 getColumnName 返回 null 表示未找到注解）
                .filter(field -> {
                    //return StrUtil.isNotEmpty(field);
                    String columnName = ConvertUtil.getAnnotationValue(User.class, field, TableField.class);
                    return StrUtil.isNotEmpty(columnName);
                })
                .map(field -> {
                    String columnName = ConvertUtil.getAnnotationValue(User.class, field, TableField.class);
                    boolean isAsc = ascs != null && ascs.contains(field);
                    return isAsc ? OrderItem.asc(columnName) : OrderItem.desc(columnName);

                    // 注意：由于我们丢失了原始的 field 信息，这里我们可能无法直接创建 OrderItem(field)
                    // 如果 OrderItem 需要原始的 field 信息，那么我们需要重新设计这个流程
                    // 如果只需要 columnName，那么我们可以直接创建 OrderItem(columnName)
                    // 但这通常不是个好主意，因为 OrderItem 通常应该与数据库字段或实体属性对应，而不是与数据库列名对应

                    // 假设我们在这里只关心排序方向和列名，并且 OrderItem 可以接受列名作为参数
//                    boolean isAsc = ascs != null && ascs.contains(columnName);
//                    return isAsc ? OrderItem.asc(columnName) : OrderItem.desc(columnName);
                })
                .collect(Collectors.toList());

        if (orderItems.size() == 0) {
            orderItems.add(OrderItem.desc("create_time"));
        }
        Page page = new Page(pageParam.getPageIndex(), pageParam.getPageSize());
        page.setOrders(orderItems);
        return page;
    }


    /**
     * 根据 Body 条件，构建分页数
     *
     * @param paramMap
     */
    protected <T> Page buildPage(Map<String, Object> paramMap, Class<T> clazz) {
        List<OrderItem> orderItems = new ArrayList<>();
        if (paramMap.containsKey("ascs")) {
            List<OrderItem> orderAsc = buildOrderItem(paramMap, "ascs", clazz);
            orderItems.addAll(orderAsc);
        }
        if (paramMap.containsKey("descs")) {
            List<OrderItem> orderAsc = buildOrderItem(paramMap, "descs", clazz);
            orderItems.addAll(orderAsc);
        }
        if (orderItems.size() == 0) {
            //默认按创建时间排序
            orderItems.add(OrderItem.desc("create_time"));
        }
        long pageIndex = paramMap.containsKey("pageIndex") ? Long.valueOf((int) paramMap.get("pageIndex")) : 1;
        long pageSize = paramMap.containsKey("pageSize") ? Long.valueOf((int) paramMap.get("pageSize")) : 10;
        Page page = new Page(pageIndex, pageSize);
        page.setOrders(orderItems);
        return page;
    }

    /**
     * 构建排序字段
     *
     * @param paramMap
     * @param order
     * @return
     */
    private <T> List<OrderItem> buildOrderItem(Map<String, Object> paramMap, String order, Class<T> clazz) {
        List<OrderItem> orderItems = new ArrayList<>();
        if (paramMap.containsKey(order)) {
            String orderField = paramMap.get(order).toString();  //格式是 "field1,field2,..."
            if (StrUtil.isNotEmpty(orderField)) {
                String[] split = orderField.split(",");
                for (String field : split) {
                    String columnName = ConvertUtil.getAnnotationValue(clazz, field, TableField.class);
                    if (order.equals("ascs")) {
                        orderItems.add(OrderItem.asc(columnName));
                    }
                    if (order.equals("descs")) {
                        orderItems.add(OrderItem.desc(columnName));
                    }
                }
            }

        }
        return orderItems;
    }

    /**
     * 构建查询条件
     *
     * @param clazz
     * @param queryMap
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked") //抑制编译器产生的类型检查警告
    protected <T> QueryWrapper<T> buildQueryWrapper(Class<T> clazz, Map<String, Object> queryMap) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        boolean hasStatusField = false;
        for (String key : queryMap.keySet()) {
            if (!key.contains("__")) {
                continue;
            }
            String[] spKey = key.split("__");
            String field = spKey[0];
            String condition = spKey[1];
            hasStatusField = field.equals("status");
            if(field.equals("id")){
                field = ConvertUtil.getAnnotationValue(clazz, field, TableId.class); //转成DB字段
            }
            else{
                field = ConvertUtil.getAnnotationValue(clazz, field, TableField.class); //转成DB字段
            }
            if(StrUtil.isEmpty(field)){
                logger.warn("查询条件{}，非数据库字段",spKey[0]);
                continue;
            }
            if (condition.equals(QueryCondition.IS_NULL)) {
                queryWrapper.isNull(field);
            }
            Object val = queryMap.get(key);
            if(ObjectUtil.isEmpty(val)){
                continue;
            }
            if (condition.equals(QueryCondition.EQ)) {
                queryWrapper.eq(field, val);
            }
            if (condition.equals(QueryCondition.NE)) {
                queryWrapper.ne(field, val);
            }
            if (condition.equals(QueryCondition.GT)) {
                queryWrapper.gt(field, val);
            }
            if (condition.equals(QueryCondition.GE)) {
                queryWrapper.ge(field, val);
            }
            if (condition.equals(QueryCondition.LT)) {
                queryWrapper.lt(field, val);
            }
            if (condition.equals(QueryCondition.LE)) {
                queryWrapper.le(field, val);
            }
            if (condition.equals(QueryCondition.LIKE)) {
                queryWrapper.like(field, val);
            }
            if (condition.equals(QueryCondition.NOT_LIKE)) {
                queryWrapper.notLike(field, val);
            }
            if (condition.equals(QueryCondition.LIKE_LEFT)) {
                queryWrapper.likeLeft(field, val);
            }
            if (condition.equals(QueryCondition.LIKE_RIGHT)) {
                queryWrapper.likeRight(field, val);
            }
            if (condition.equals(QueryCondition.IN)) {
                queryWrapper.in(field, ((ArrayList) val).toArray());
            }
            if (condition.equals(QueryCondition.NOT_IN)) {
                queryWrapper.notIn(field, ((ArrayList) val).toArray());
            }
            if (condition.equals(QueryCondition.BT)) {
                Object param1 = ((ArrayList) val).get(0);
                Object param2 = ((ArrayList) val).get(1);
                queryWrapper.between(field, param1, param2);
            }
            if (condition.equals(QueryCondition.GLE)) {
                Object param1 = ((ArrayList) val).get(0);
                Object param2 = ((ArrayList) val).get(1);
                queryWrapper.ge(field, param1);
                queryWrapper.le(field, param2);
            }
        }
        if (!hasStatusField) {
            //默认不显示删除的数据
            queryWrapper.ne("status", 3);
        }
        return queryWrapper;
    }

}
